package com.dnjn.happiness.fer.controller;

import com.alibaba.fastjson.JSON;
import com.dnjn.happiness.common.core.controller.BaseController;
import com.dnjn.happiness.common.core.domain.AjaxResult;
import com.dnjn.happiness.common.utils.JsonUtils;
import com.dnjn.happiness.common.utils.StringUtils;
import com.dnjn.happiness.oss.config.MinioClientConfig;
import com.dnjn.happiness.oss.minio.MinioTemplate;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/fer/open")
public class FerOpenController extends BaseController {

    private static  final Logger log_hk = LoggerFactory.getLogger("hk_fer");

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MinioTemplate minioTemplate;
    @Autowired
    private MinioClientConfig minioConfig;

    /**
     * 监听接口事件解析 海康demo
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @PostMapping("/uploadFileDemo")
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //解析multipart/form-data类型报文
        log.info("content type: {} {}", request.getContentType(), request.getClass().getCanonicalName());
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload sf = new ServletFileUpload(factory);
        try {
            log.info("is multi {}", ServletFileUpload.isMultipartContent(request));
            if (ServletFileUpload.isMultipartContent(request)) {
                List<FileItem> formData = sf.parseRequest(request);
                log.info("form data FileItem size {}", formData.size());
                for (FileItem fi : formData) {
                    log.info("field_name:" + fi.getFieldName());
                    if (fi.isFormField()) {
                        //解析报文中json
                        log.info("field_name:" + fi.getFieldName());
                        //打印json格式上传的事件报文
                        log.info(fi.getString("UTF-8"));
                        //通过表单name属性进行解析报文
                        switch (fi.getFieldName()) {
                            case "event_log"://门禁、身份证事件解析
                                log.info("receive Acs event {}", fi.getString("UTF-8"));
                                break;
                            default:
                                log.info("unknow data");
                        }
                    } else {
                        //保存报文中的图片数据
                        String image_name = fi.getName();
                        log.info("image_name:" + image_name);
                        if (image_name != "") {
                            //图片保存路径
                            String image_dir_path = "/tmp/";

                            File image_dir = new File(image_dir_path);
                            if (!image_dir.exists()) {
                                image_dir.mkdir();
                            }
                            String file_name = UUID.randomUUID().toString();
                            String suffix = image_name.substring(fi.getName().lastIndexOf("."));
                            log.info("图片报文路径:" + image_dir_path);
                            log.info("图片名称:" + file_name);
                            log.info("图片格式:" + suffix);
                            fi.write(new File(image_dir_path, file_name + suffix));
                        } else {
                            throw new Exception("no file receive");
                        }
                    }
                }
            }
            //application/json报文解析
            else {
                //报文解析
                String Content_Type = request.getContentType();
                BufferedReader reader = request.getReader();
                StringBuilder requestData = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    requestData.append(line);
                }
                if (Content_Type.contains("application/json")) {
                    Object jsonObject = JSON.parse(requestData.toString());
                    // 打印JSON对象
                    log.info(jsonObject.toString());
                }

            }

            //正常接收平台响应回复
            response.getWriter().write("success");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            response.getWriter().write("false");
        }
    }

    /**
     * http://happy.jinkosolar.com/api/fer/open/uploadFile
     * 24.08.14
     * 海康设备上传文件
     */
    @PostMapping(value = "/uploadFile")
    public AjaxResult uploadFile(/*@RequestPart(value = "event_log", required = false) EventLog eventLog, */HttpServletRequest request) {
        log.info("content type: {} {}", request.getContentType(), request.getClass().getCanonicalName());
        try {
            if (!ServletFileUpload.isMultipartContent(request)) {
                throw new Exception("no multipartcontent");
            }
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;

          /*
          FileItemFactory factory = new DiskFileItemFactory();
          ServletFileUpload sf = new ServletFileUpload(factory);
          List<FileItem> formData = sf.parseRequest(request);
            String event_log = null;
            FileItem fileItem = null;
            for (FileItem el : formData) {
                log.info("fieldName: {}", el.getFieldName());
                if ("event_log".equals(el.getFieldName())) {
                    event_log = el.getString();
                }
                if ("Picture".equals(el.getFieldName())) {
                    fileItem = el;
                }
            }
            Assert.isTrue(StringUtils.isNotBlank(event_log),"event log is blank");
            //Map<String, FileItem> map = formData.stream().collect(Collectors.toMap(FileItem::getFieldName, Function.identity()));
            //String event_log = map.get("event_log").getString();
            log.info("event_log: {}", JsonUtils.toJsonString(event_log));
            EventLog eventLog = JsonUtils.parseObject(event_log, EventLog.class);
            */
            String evtLogStr = multiRequest.getParameter("event_log");
            log.info("event log {}", evtLogStr);
            EventLog eventLog = JsonUtils.parseObject(evtLogStr, EventLog.class);
            boolean flag = Optional.ofNullable(eventLog)
                    .map(EventLog::getAccessControllerEvent)
                    .filter(evt -> (0x5 == evt.getMajorEventType() && 0x4b == evt.getSubEventType()))
                    .isPresent();

            if (flag) {
                MultipartFile file = multiRequest.getFile("Picture");

                List<String> upload = minioTemplate.upload(minioConfig.getBucketName(), "ferImg", new MultipartFile[]{file});
                String path = StringUtils.format("{}/{}/{}", minioConfig.getPublishHost(), minioConfig.getBucketName(), upload.get(0));
                log.info(" minio path {}", path);
                log_hk.info("path {}, event_log {} ", path, evtLogStr);
                String empno = eventLog.getAccessControllerEvent().getEmployeeNoString();
                Assert.isTrue(StringUtils.isNotEmpty(empno), "empno.invalid; failed");

            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return error(e.getMessage());
        }
        return success();
    }

    /**
     * 24.08.14
     * 海康设备上传文件
     */
    @PostMapping(value = "/uploadFileA")
    public AjaxResult uploadFileA(@RequestPart(value = "Picture", required = false) MultipartFile file, @RequestPart(value = "event_log", required = false) EventLog eventLog, HttpServletRequest req) {

        String contentType = req.getContentType();
        log.info("contentType: {}", contentType);

//        if(contentType.contains("multipart/form-data")) {//文件上传请求 *特殊请求
//            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
//            MultipartHttpServletRequest multiReq = multipartResolver.resolveMultipart(req);
//
//            req= multiReq;
//
//        }
        log.info("fer-uploadFile checkon meta: {} {} {}", JsonUtils.toJsonString(eventLog), file.getOriginalFilename(), file.getContentType());
        boolean flag = Optional.ofNullable(eventLog)
                .map(EventLog::getAccessControllerEvent)
                .filter(evt -> (0x5 == evt.getMajorEventType() && 0x4b == evt.getSubEventType()))
                .isPresent();
        if (flag) {
            String empno = eventLog.getAccessControllerEvent().getEmployeeNoString();
            Assert.isTrue(StringUtils.isNotEmpty(empno), "empno.invalid; failed");

            List<String> upload = minioTemplate.upload(minioConfig.getBucketName(), "ferImg", new MultipartFile[]{file});
            String path = StringUtils.format("{}/{}/{}", minioConfig.getPublishHost(), minioConfig.getBucketName(), upload.get(0));

        }

        return success();
    }

    @Getter
    @Setter
    public static class EventLog implements Serializable {
        private String eventType;
        private String eventState;
        @JsonProperty("deviceID")
        private String deviceID;
        @JsonProperty("AccessControllerEvent")
        private AccessControllerEvent AccessControllerEvent;
        private String ipAddress;


        @Getter
        @Setter
        public static class AccessControllerEvent implements Serializable {
            private Integer majorEventType;
            private Integer subEventType;
            private String cardNo;
            private Integer cardType;
            private String name;
            private Integer employeeNo;
            private String employeeNoString;
            private String employeeName;

            private Integer statusValue;

            private String pictureURL;
            private Integer picturesNumber;
        }
    }

}
